package controller

import (
	"GoAdmin/common"
	"GoAdmin/models"
	"GoAdmin/utils"
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/astaxie/beego/validation"
	"github.com/gin-gonic/gin"
	"github.com/mozillazg/request"
	"github.com/spf13/cast"
	"github.com/tealeg/xlsx"
	"hash"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
	"xorm.io/builder"
)

var (
	file  *xlsx.File
	sheet *xlsx.Sheet
	row   *xlsx.Row
	cell  *xlsx.Cell
)

func StudentInformation(c *gin.Context) {
	var (
		name      string
		phone     string
		idNumber  string
		startTime string
		endTime   string
		schoolId  string
	)
	page, _ := strconv.Atoi(c.DefaultPostForm("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultPostForm("pageSize", "20"))
	offset := (page - 1) * pageSize
	user, _ := common.GetCtxUser(c)
	filter := builder.NewCond()
	if user.Type == "0" || user.Type == "1" {
		//管理用户查询全部
	} else {
		if user.Province != "" {
			filter = filter.And(builder.Eq{"sl.province": user.Province})
		}
		if user.City != "" {
			filter = filter.And(builder.Eq{"sl.city": user.City})
		}
		if user.District != "" {
			filter = filter.And(builder.Eq{"sl.district": user.District})
		}
	}
	if user.Type == "3" {
		//同一个地区双代理
		filter = filter.And(builder.Eq{"sl.config": user.SchoolList})
	}
	if schoolId = c.PostForm("school_id"); schoolId != "" {
		filter = filter.And(builder.Eq{"st.school_id": schoolId})
	}
	if name = c.PostForm("name"); name != "" {
		filter = filter.And(builder.Eq{"u.name": name})
	}
	if phone = c.PostForm("phone"); phone != "" {
		filter = filter.And(builder.Eq{"u.phone": phone})
	}
	if idNumber = c.PostForm("id_number"); idNumber != "" {
		filter = filter.And(builder.Eq{"u.id_number": idNumber})
	}
	if startTime = c.PostForm("start_time"); startTime != "" {
		filter = filter.And(builder.Gte{"st.addtime": startTime + " 00:00:00"})
	}
	if endTime = c.PostForm("end_time"); endTime != "" {
		filter = filter.And(builder.Lte{"st.addtime": endTime + " 23:59:59"})
	}
	filter = filter.And(builder.Eq{"u.type": "4"}).And(builder.Eq{"st.isused": "1"})
	count, list, _ := new(models.Student).GetStudentByFilter(filter, pageSize, offset)
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "成功", "data": gin.H{"list": list, "count": count}})
	return
}

func StudentDetail(c *gin.Context) {
	var (
		studentId string
	)
	log.Println(c.PostForm("student_id"))
	if studentId = c.PostForm("student_id"); studentId == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	has, stuDtail, _ := new(models.Student).GetStudentDetailInfo(studentId)
	if !has {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "成功", "data": stuDtail})
	return
}

var Syllabus = map[string]interface{}{
	"370000": map[string]interface{}{
		"subject1": "",
	},
}

func Record(c *gin.Context) {
	var (
		studentId string
		carType   string
	)
	log.Println(c.PostForm("student_id"))
	if studentId = c.PostForm("student_id"); studentId == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	if carType = c.PostForm("car_type"); carType == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	//大纲学时
	carInfo, _ := new(models.TrainCarinfo).GetTrainCarinfo(carType)
	//已完成学时
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "成功", "data": carInfo})
	return
}

func StudentDelete(c *gin.Context) {
	var (
		schoolId string
	)
	if schoolId = c.PostForm("school_id"); schoolId == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	school, _ := new(models.School).GetSchool(schoolId)
	if school.Id <= 0 {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	reqUrl := BaeUrl + `/student/unregisterStudent`
	data := url.Values{}
	data.Set("id", c.PostForm("id"))
	data.Set("province", school.Province)
	data.Set("city", school.City)
	data.Set("school_id", c.PostForm("school_id"))
	data.Set("subject", c.PostForm("subject"))
	log.Println(data)
	resp, err := utils.PostForm(reqUrl, data)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error(), "data": nil})
		return
	}
	repMap, _ := cast.ToStringMapE(resp)
	c.JSON(http.StatusOK, gin.H{"code": cast.ToInt(repMap["code"]), "msg": cast.ToString(repMap["msg"]), "data": nil})
	return
}

var UnregisterReasonCodeBinding = map[string]string{
	"1": "转校",
	"2": "驾校换平台",
	"3": "退学",
	"4": "学员自动注销",
	"9": "其他",
}

func validReasonCode(reason string) bool {
	if _, ok := UnregisterReasonCodeBinding[reason]; ok {
		return true
	}

	return false
}

func validDelStuParams(performerId string, schId string, userId string, reason string) bool {
	return len(strings.TrimSpace(performerId)) > 0 &&
		len(strings.TrimSpace(schId)) > 0 &&
		len(strings.TrimSpace(userId)) > 0 &&
		validReasonCode(reason)
}

func UnregisterStudent(c *gin.Context) {
	schId := c.PostForm("sch_id")
	student_id := c.PostForm("stu_uid") // NOTE: stu_uid -> dts_user::ID
	reasonId := c.PostForm("reason_id")
	performerId := c.PostForm("user_id")
	var has bool
	var student models.Student
	var user models.User

	if !validDelStuParams(performerId, schId, student_id, reasonId) {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "参数错误", "data": nil})
		return
	}

	// 平台参数验证
	school, err := new(models.School).GetSchool(schId)
	if err != nil || school.Id <= 0 {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "未能获取驾校信息", "data": nil})
		return
	}
	if has, student, _ = new(models.Student).GetOneStudent(student_id); !has {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员未找到", "data": nil})
		return
	}

	user, _ = new(models.User).GetById(cast.ToString(student.UserId))

	// 调用省监管平台接口, 解除备案关系
	if school.Province != "520000" {
		err = unregisterStudent(school.InstitutionCode, student.InstitutionCode, reasonId, school.Province, school.City)
		if err != nil {
			if err.Error() == "该学员已经处于解除备案状态！" || err.Error() == "该学员不存在，请检查驾校编号和学员编号是否正确！" || err.Error() == "该学员已经处于解除备案状态或已退学！" {

			} else {
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error(), "data": err})
				return
			}
		}
	}

	kyschool, _, _ := new(models.KyappSchool).GetBySchoolId(school.Id)
	var resp string
	if kyschool && (student.TrainingCarType == "C1" || student.TrainingCarType == "C2") {
		//code, msg := DelStudentToKy(school.Id, user.Name, user.Phone, user.IdNumber, student.TrainingCarType, student.SignInTime.Format("2006-01-02"))
		//log.Println(code, msg)
		//resp = msg
	}
	// 更新计时平台学员备案状态
	student.RecordStatus = "0"
	student.Isused = "0"
	student.Remark = student.InstitutionCode
	student.InstitutionCode = ""
	affectedRows := student.Update(cast.ToString(student.Id), "record_status", "isused", "remark", "institution_code")
	if !affectedRows {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员备案状态更新失败", "data": nil})
		return
	}
	user.ReidNumber = user.IdNumber
	user.Remark = user.Phone
	user.IdNumber = ""
	user.Phone = fmt.Sprint(time.Now().UnixNano() / 1e6)
	user.Isused = "0"
	if !user.Edit("phone", "id_number", "remark", "reid_number", "isused") {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员备案状态更新失败", "data": nil})
		return
	}
	status := "0"
	beforeNumber := school.Usednum
	//删除学员检查有没有学时，没有学时返还名额
	currtimes, _ := time.ParseInLocation("2006-01-02 15:04:05", "2023-01-01 00:00:00", time.Now().Location())
	if school.City == "420100" && school.Config == 1 {
		//武汉学员不管有没有学时都不退名额
	} else if school.City == "371400" && student.Addtime.Before(currtimes) {
		//德州早于2023年录入的退学不返还名额
	} else {
		if has, _, _ := new(models.LearnRecord).GetLastRecordTime(student.Id, int64(student.SchoolId)); !has {
			log.Println(school.Usednum)
			school.Usednum = school.Usednum - 1
			log.Println(school.Usednum)
			status = "1"
			if !school.EditSchool("usednum") {
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "添加学员名额失败", "data": nil})
				return
			}
		}
	}
	creator, _ := common.GetCtxUser(c)
	// 将已解除备案的学员写入到解除备案记录表中
	performer, _ := strconv.ParseInt(performerId, 10, 64)
	var record models.StuUnregisterRecord
	record.PerformerUid = performer
	record.SchoolId = school.Id
	record.UserId = student.UserId
	record.StudentId = student.Id
	record.ReasonId = reasonId
	record.BeforeNumber = beforeNumber
	record.Status = "1"
	record.Resp = resp
	record.Creator = creator.Id
	record.ChangeStatus = status
	record.Ip = ClientIP(c.Request)
	ok, err := record.Add()
	if err != nil || !ok {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员解除备案记录失败", "data": nil})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "学员解除备案成功", "data": nil})
	return
}

func ClientIP(r *http.Request) string {
	xForwardedFor := r.Header.Get("X-Forwarded-For")
	ip := strings.TrimSpace(strings.Split(xForwardedFor, ",")[0])
	if ip != "" {
		return ip
	}

	ip = strings.TrimSpace(r.Header.Get("X-Real-Ip"))
	if ip != "" {
		return ip
	}

	if ip, _, err := net.SplitHostPort(strings.TrimSpace(r.RemoteAddr)); err == nil {
		return ip
	}

	return ""
}

// NOTE: 向驾校省平台解除学员和驾校的绑定关系(解除备案)
func unregisterStudent(schInstitutionCode string, stuInstitutionCode string, reason string, province, city string) error {
	var (
		u       string
		retMap  map[string]interface{}
		err     error
		reqType int64
	)

	// NOTE: 根据驾校城市 区分 平台接口地址: 全国(1)/省(2)/市区(3)
	if city == "130100" { // NOTE: 河北省石家庄市
		reqType = 3
	} else {
		reqType = 2
	}

	queryUrl := fmt.Sprintf("%s-delstudent-%s-%s", schInstitutionCode, stuInstitutionCode, reason)
	log.Println("解除备案: ", queryUrl)

	if u, err = utils.GetSignURL(queryUrl, nil, reqType, province, city); err != nil {
		log.Println(err)
		return err
	}
	log.Println(u)
	// NOTE: 记录请求日志
	var apiLog models.ApiLog
	apiLog.Url = u
	apiLog.Param = ""
	apiLog.Method = "POST"
	apiLog.Time = time.Now()
	client := new(http.Client)
	req := request.NewRequest(client)
	resp, err := req.Get(u)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)
	var (
		body []byte
	)
	if body, err = io.ReadAll(resp.Response.Body); err != nil {
		log.Println(err)
	}
	if err = json.Unmarshal(body, &retMap); err != nil {
		log.Println(err)
	}
	result, _ := json.Marshal(retMap)
	apiLog.Result = string(result)
	apiLog.Add()
	fmt.Println(retMap)
	if cast.ToFloat64(retMap["errorcode"]) == 0 {
		return nil
	}
	return errors.New(retMap["message"].(string))
}

func StudentOrder(c *gin.Context) {
	var (
		value string
	)
	page, _ := strconv.Atoi(c.DefaultPostForm("pageIndex", "1"))
	pagesize, _ := strconv.Atoi(c.DefaultPostForm("pageSize", "20"))
	offset := (page - 1) * pagesize

	filter := builder.NewCond()
	if value = c.PostForm("school_id"); value != "" {
		filter = filter.And(builder.Eq{"pt.school_id": value})
	}
	list, count, err := new(models.PayStudent).GetPayStudentList(filter, pagesize, offset)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}

	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "成功", "data": gin.H{"data": list, "total": count}})
	return
}

func StudentOrderAdd(c *gin.Context) {

}

func StudentOrderPay(c *gin.Context) {
	var (
		id         string
		payStudent models.PayStudent
		has        bool
	)
	if id = c.PostForm("id"); id == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	log.Println(id)
	if has, payStudent, _ = new(models.PayStudent).GetOnePayStudent(id); !has {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "订单不存在", "data": nil})
		return
	}
	log.Println(has, payStudent)
	payStudent.Paystatus = "1"
	if !payStudent.Update("paystatus") {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "设置失败", "data": nil})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "购买学员确认成功", "data": nil})
	return
}

func StudentOrderDelete(c *gin.Context) {
	var (
		id         string
		err        error
		payStudent models.PayStudent
		has        bool
	)
	if id = c.PostForm("id"); id == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误"})
		return
	}
	//log.Println(id)
	if has, payStudent, err = new(models.PayStudent).GetOnePayStudent(id); !has {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "订单不存在"})
		return
	}
	if payStudent.Submit == "1" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "订单已确认不允许删除"})
		return
	}
	payStudent.Isused = "0"
	if !payStudent.Update("isused") {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "设置失败"})
		return
	}
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "删除成功"})
	return
}

func StudentTransfer(c *gin.Context) {
	var (
		id      string
		student models.Student
	)
	if id = c.PostForm("id"); id == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	if c.PostForm("tran_status") == "1" {
		student.Istransfer = "0"
	} else {
		student.Istransfer = "1"
	}
	if !student.Update(id, "istransfer") {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "查询错误", "data": nil})
		return
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "设置成功", "data": nil})
	return
}

func UnRegisterList(c *gin.Context) {
	var (
		name     string
		phone    string
		idNumber string
		schoolId string
	)
	page, _ := strconv.Atoi(c.DefaultPostForm("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultPostForm("pageSize", "20"))
	offset := (page - 1) * pageSize
	user, _ := common.GetCtxUser(c)
	filter := builder.NewCond()
	if user.Type == "0" || user.Type == "1" {
		//管理用户查询全部
	} else {
		if user.Province != "" {
			filter = filter.And(builder.Eq{"sl.province": user.Province})
		}
		if user.City != "" {
			filter = filter.And(builder.Eq{"sl.city": user.City})
		}
		if user.District != "" {
			filter = filter.And(builder.Eq{"sl.district": user.District})
		}
	}
	if user.Type == "3" {
		//同一个地区双代理
		filter = filter.And(builder.Eq{"sl.config": user.SchoolList})
	}
	if schoolId = c.PostForm("school_id"); schoolId != "" {
		filter = filter.And(builder.Eq{"st.school_id": schoolId})
	}
	if name = c.PostForm("name"); name != "" {
		filter = filter.And(builder.Eq{"u.name": name})
	}
	if phone = c.PostForm("phone"); phone != "" {
		filter = filter.And(builder.Eq{"u.remark": phone})
	}
	if idNumber = c.PostForm("id_number"); idNumber != "" {
		filter = filter.And(builder.Eq{"u.reid_number": idNumber})
	}
	filter = filter.And(builder.Eq{"u.type": "4"})
	count, list, _ := models.GetUnList(filter, pageSize, offset)
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "设置成功", "data": gin.H{"list": list, "count": count}})
	return
}

func UnRegisterRestore(c *gin.Context) {
	valid := validation.Validation{}
	valid.Required(c.PostForm("id"), "id").Message("学员信息不正确")
	valid.Required(c.PostForm("phone"), "phone").Message("手机号不正确")
	valid.Required(c.PostForm("id_number"), "id_number").Message("身份证不正确")
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Message, "data": nil})
			return
		}
	} else {
		//检测手机号身份证号唯一
		if models.HasPhone(c.PostForm("phone")) || models.HasIdNumber(c.PostForm("id_number")) {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "手机号或者身份证已经存在系统中，先确认学员信息", "data": nil})
			return
		}
		unStu, err := models.GetById(c.PostForm("id"))
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "信息查询错误", "data": nil})
			return
		}
		has, student, err := new(models.Student).GetStudentById(cast.ToString(unStu.StudentId))
		if !has || err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员信息不存在", "data": nil})
			return
		}
		student.InstitutionCode = student.Remark
		student.Isused = "1"
		student.Edit("institution_code", "isused")
		user, err := new(models.User).GetById(cast.ToString(unStu.UserId))
		if err != nil {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员信息不存在", "data": nil})
			return
		}
		user.Phone = user.Remark
		user.IdNumber = user.ReidNumber
		user.Isused = "1"
		user.Edit("phone", "id_number", "isused")
		if unStu.ChangeStatus == "1" {
			school, _ := new(models.School).GetById(cast.ToString(unStu.SchoolId))
			school.Usednum = school.Usednum - 1
			if !school.EditSchool("usednum") {
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "名额恢复失败", "data": nil})
				return
			}
			c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "信息恢复，需在后台重新备案学员信息（名额扣除一个）", "data": nil})
			return
		} else {
			c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "信息恢复，需在后台重新备案学员信息", "data": nil})
			return
		}
	}
}

func ToC1(c *gin.Context) {
	valid := validation.Validation{}
	valid.Required(c.PostForm("student_id"), "student_id").Message("学员信息不正确")
	if valid.HasErrors() {
		for _, err := range valid.Errors {
			c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Message, "data": nil})
			return
		}
	} else {
		has, student, err := new(models.Student).GetStudentById(c.PostForm("student_id"))
		if !has || err != nil {
			return
		}
		student.InstitutionCode = ""
		student.TrainingCarType = "C1"
		student.RecordStatus = "0"
		student.Edit("institution_code", "training_car_type", "record_status")
		c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "变更成功，需重新备案学员信息", "data": nil})
		return
	}

}

func RemoveJieYe(c *gin.Context) {
	sid := c.PostForm("stu_id") // 学员id

	err := new(models.Graduation).Remove(sid)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "删除失败", "data": nil})
		return
	}
	_, student, _ := new(models.Student).GetOneStudent(sid)
	student.Status = "0"
	student.Subject3isreport = "1"
	student.Edit("status", "subject3isreport")
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "成功", "data": nil})
	return
}

func NeedGraduationStudentList(c *gin.Context) {
	var (
		value    string
		schoolId string
		list     []*models.FutureGraduationStudent
		err      error
		//count    int64
	)
	//获取页码
	page, _ := strconv.Atoi(c.DefaultPostForm("page", "1"))
	pageSize, _ := strconv.Atoi(c.DefaultPostForm("pageSize", "20"))
	offset := (page - 1) * pageSize
	filter := builder.NewCond()

	//获取参数
	if schoolId = c.PostForm("school_id"); schoolId != "" {
		filter = filter.And(builder.Eq{"st.school_id": schoolId})
	}
	if value = c.PostForm("name"); value != "" {
		filter = builder.Like{"ur.name", value}
	}
	if value = c.PostForm("phone"); value != "" {
		filter = filter.And(builder.Like{"ur.phone", value})
	}
	if value = c.PostForm("training_car_type"); value != "" {
		filter = filter.And(builder.Eq{"st.training_car_type": value})
	}
	if c.PostForm("city") == "511300" || c.PostForm("city") == "371600" {
		filter = filter.And(builder.Eq{"st.subject1isreport": "1"})
		filter = filter.And(builder.Eq{"st.subject2isreport": "1"})
		filter = filter.And(builder.Eq{"st.subject3isreport": "1"})
		filter = filter.And(builder.Eq{"st.subject4isreport": "1"})
	} else {
		filter = filter.And(builder.Eq{"st.subject3isreport": "1"})
	}
	list, err, _ = new(models.Student).GetFutureGraduation(schoolId, filter, pageSize, offset)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	data := map[string]interface{}{}
	student_list := []interface{}{}
	for _, v := range list {
		//过滤掉已结业
		has, _, _ := new(models.Graduation).GetGraduationByStudedntId(v.Id)
		if !has {
			exam := "0"
			exsit, _, _ := new(models.LearnRecord).CheckRecordExsit(v.Id)
			if v.OperationStatus == "12" || v.OperationStatus == "11" {
				if exsit {
					exam = "1"
				} else {
					exam = "0"
				}
			} else {
				exam = "2"
			}
			data = map[string]interface{}{
				"Id":                v.Id,
				"Name":              v.Name,
				"OperationStatus":   v.OperationStatus,
				"Id_number":         strings.Replace(v.Id_number, "t", "", -1),
				"Phone":             strings.Replace(v.Phone, "t", "", -1),
				"Sign_in_time":      v.Sign_in_time,
				"Training_car_type": v.Training_car_type,
				"Exam":              exam,
			}
			student_list = append(student_list, data)

		}
	}
	//返回结果
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "获取待结业学员管理列表", "data": gin.H{"count": len(student_list), "list": student_list}})
	return
}

func DelFromKy(c *gin.Context) {
	student, err := new(models.StuUnregisterRecord).GetList(c.PostForm("id"))
	if err != nil {
		return
	}
	_, kySchool, err := new(models.KyappSchool).GetBySchoolId(student.SchoolId)
	code, msg := DelStudentToKy(kySchool.KySchoolId, student.IdNumber)
	log.Println(code, msg)
	if code == "0" {
		c.JSON(http.StatusOK, gin.H{"code": 200, "msg": msg})
		return
	} else {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": msg})
		return
	}
}

func DelStudentToKy(schoolId int, idNum string) (code, msg string) {
	var (
		reqUrl string
		retMap map[string]interface{}
	)

	idNum = strings.Replace(idNum, "t", "", -1)
	ok, kySchool, err := new(models.KyappSchool).GetKyBySchoolId(schoolId)
	if !ok || err != nil {
		return "1", "原驾校不存在"
	}
	ts := cast.ToString(time.Now().Unix())

	templateSend := []byte(fmt.Sprintf("idcard=%s&school_id=%s&token=%s&ts=%s", idNum, cast.ToString(kySchool.KySchoolId), kySchool.Token, ts))

	log.Println("加密内容", string(templateSend))
	var h hash.Hash
	h = sha1.New()
	if _, err := h.Write(templateSend); err != nil {
		log.Println("数据加密失败", err.Error())
		return "1", err.Error()
	}
	reqUrl = "https://api.kuaiyazhineng.com/api/school/hahajishidelstu?idcard=" + idNum + "&school_id=" + cast.ToString(kySchool.KySchoolId) + "&ts=" + ts + "&sign=" + hex.EncodeToString(h.Sum(nil))
	log.Println(reqUrl)
	resp, err := http.Get(reqUrl)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)
	if err != nil {
		log.Println(err.Error())
		return "1", err.Error()
	}
	content, _ := ioutil.ReadAll(resp.Body)
	log.Println(string(content))
	err = json.Unmarshal(content, &retMap)
	if err != nil {
		return "1", err.Error()
	}
	if cast.ToString(retMap["code"]) != "200" {
		return "1", cast.ToString(retMap["msg"])
	}

	return "0", cast.ToString(retMap["msg"])
}

func PushToKy(c *gin.Context) {
	var (
		reqUrl  string
		retMap  map[string]interface{}
		retMap2 map[string]interface{}
	)
	ok, student, err := new(models.Student).GetStudentSchool(c.PostForm("id"))
	if !ok || err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员信息错误"})
		return
	}
	url.QueryEscape(student.Name)

	idNum := strings.Replace(student.IdNumber, "t", "", -1)
	ok, kySchool, err := new(models.KyappSchool).GetBySchoolId(student.SchoolId)
	if !ok || err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "学员信息错误"})
		return
	}
	ts := cast.ToString(time.Now().Unix())

	templateSend := []byte(fmt.Sprintf("car_type=%s&enrolltime=%s&idcard=%s&name=%s&school_id=%s&telphone=%s&token=%s&ts=%s", student.TrainingCarType, student.SignInTime, idNum, url.QueryEscape(student.Name), cast.ToString(kySchool.KySchoolId), student.Phone, kySchool.Token, ts))

	log.Println("加密内容", string(templateSend))
	var h hash.Hash
	h = sha1.New()
	if _, err := h.Write(templateSend); err != nil {
		log.Println("数据加密失败", err.Error())
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	reqUrl = "https://api.kuaiyazhineng.com/api/school/savehahajishistudent?car_type=" + student.TrainingCarType + "&enrolltime=" + student.SignInTime + "&idcard=" + idNum + "&name=" + url.QueryEscape(student.Name) + "&school_id=" + cast.ToString(kySchool.KySchoolId) + "&telphone=" + student.Phone + "&ts=" + ts + "&sign=" + hex.EncodeToString(h.Sum(nil))
	log.Println(reqUrl)
	resp, err := http.Get(reqUrl)
	defer func(Body io.ReadCloser) {
		err := Body.Close()
		if err != nil {

		}
	}(resp.Body)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	content, _ := ioutil.ReadAll(resp.Body)
	log.Println(string(content))
	err = json.Unmarshal(content, &retMap)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
		return
	}
	log.Println(retMap["code"])
	//if cast.ToString(retMap["code"]) == "401" {
	//	// 异常情况先删除快鸭
	//	data := cast.ToStringMap(retMap["data"])
	//	other := cast.ToStringMap(data["other"])
	//	log.Println(cast.ToString(other["idcard"]))
	//	log.Println(cast.ToString(other["school_id"]))
	//	code, msg := DelStudentToKy(cast.ToInt(other["school_id"]), student.IdNumber)
	//	log.Println(code, msg)
	//	if code == "0" {
	//		c.JSON(http.StatusOK, gin.H{"code": 200, "msg": msg})
	//		return
	//	} else {
	//		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": msg})
	//		return
	//	}
	//} else
	if cast.ToString(retMap["code"]) != "200" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": cast.ToString(retMap["msg"])})
		return
	} else if cast.ToString(retMap["code"]) == "200" {
		//广汉市推送学员头像
		if student.District == "510681" {
			student.Image = url.QueryEscape(student.Image)
			ts2 := cast.ToString(time.Now().Unix())
			templateSend2 := []byte(fmt.Sprintf("checkface=%s&faceimgurl=%s&idcard=%s&school_id=%s&token=%s&ts=%s", "0", student.Image, idNum, cast.ToString(kySchool.KySchoolId), kySchool.Token, ts2))

			log.Println("加密内容", string(templateSend2))
			var h2 hash.Hash
			h2 = sha1.New()
			if _, err := h2.Write(templateSend2); err != nil {
				log.Println("数据加密失败", err.Error())
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
				return
			}
			reqUrl2 := "https://api.kuaiyazhineng.com/api/school/setface?checkface=0&faceimgurl=" + student.Image + "&idcard=" + idNum + "&school_id=" + cast.ToString(kySchool.KySchoolId) + "&ts=" + ts2 + "&sign=" + hex.EncodeToString(h2.Sum(nil))
			log.Println(reqUrl2)
			resp, err := http.Get(reqUrl2)
			defer func(Body io.ReadCloser) {
				err := Body.Close()
				if err != nil {

				}
			}(resp.Body)
			if err != nil {
				log.Println(err.Error())
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
				return
			}
			content, _ := ioutil.ReadAll(resp.Body)
			log.Println(string(content))
			err = json.Unmarshal(content, &retMap2)
			if err != nil {
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": err.Error()})
				return
			}
			if cast.ToString(retMap2["code"]) != "200" {
				c.JSON(http.StatusOK, gin.H{"code": 201, "msg": cast.ToString(retMap2["msg"])})
				return
			} else {
				c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "同步成功"})
				return
			}
		}
		c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "同步成功"})
		return
	}

}

func StudentExport(c *gin.Context) {
	var (
		err         error
		list        []*models.DownStudent
		currShowStr []string

		showStr map[string]string = map[string]string{
			"name":               "学员员姓名",
			"sex":                "性别",
			"id_number":          "身份证号",
			"id_type":            "证件类型",
			"phone":              "手机号码",
			"address":            "联系地址",
			"image_url":          "头像地址",
			"finger_url":         "指纹地址",
			"licence_number":     "驾驶证号",
			"licence_grant_date": "驾驶证初领日期",
			"driving_car_type":   "原准驾车型",
			"training_car_type":  "培训车型",
			"status":             "培训部分",
			"institution_code":   "统一编号",
			"sign_in_time":       "报名日期",
			"class_name":         "班级名称",
			"charge_mode":        "缴费方式",
			"nationality":        "国籍",
			"operation_status":   "业务类型",
		}
	)
	filter := builder.NewCond()
	if username := c.PostForm("name"); username != "" {
		filter = filter.And(builder.Like{"u.name", username})
	}
	if phone := c.PostForm("phone"); phone != "" {
		filter = filter.And(builder.Like{"u.phone", phone})
	}
	if idNumber := c.PostForm("id_number"); idNumber != "" {
		filter = filter.And(builder.Like{"u.id_number", idNumber})
	}
	if status := c.PostForm("status"); status != "" {
		filter = filter.And(builder.Eq{"c.status": status})
	}
	if trainingCarType := c.PostForm("training_car_type"); trainingCarType != "" {
		filter = filter.And(builder.Eq{"c.training_car_type": trainingCarType})
	}
	if startTime := c.PostForm("start_time"); startTime != "" {
		filter = filter.And(builder.Gte{"c.addtime": startTime})
	}
	if endTime := c.PostForm("end_time"); endTime != "" {
		filter = filter.And(builder.Lte{"c.sign_in_time": endTime})
	}
	list, err = new(models.Student).GetDownStudent(filter)
	if exportData := c.PostForm("exportdata"); exportData == "" {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "请选择导出项"})
		return
	} else {
		currShowStrArr := c.PostForm("exportdata")
		currShowStr = strings.Split(currShowStrArr, ",")
	}
	filename := GetFileName()
	file = xlsx.NewFile()
	sheet, _ = file.AddSheet("学员")
	fmt.Println(list)
	fmt.Println(len(list))
	if len(list) <= 0 {
		c.JSON(http.StatusOK, gin.H{"code": 201, "msg": "数据不存在"})
		return
	}
	for k, v := range list {
		if k == 0 {
			SetHeader(sheet, showStr, currShowStr)
		}
		SetContents(sheet, v, currShowStr, "1")
	}
	dir, err := ExcelDir()
	err = file.Save(dir + "/" + filename)
	if err != nil {
		fmt.Printf(err.Error())
	}
	downDir := time.Now().Format("20060102") + "/" + filename
	downDir = UploadOss(downDir)
	c.JSON(http.StatusOK, gin.H{"code": 200, "msg": "导出成功", "data": downDir})
	return
}

func GetFileName() (filename string) {
	t := time.Now().Unix()
	year := time.Now().Format("2006")
	month := time.Now().Format("01")
	day := time.Now().Format("02")
	r := rand.Int63n(1000)
	filename = fmt.Sprintf("%s%s%s%d%d.xlsx", year, month, day, t, r)
	return
}
